package com.translation.assistant.manager

import android.content.Context
import android.text.TextUtils
import android.util.Log
import com.huawei.agconnect.config.AGConnectServicesConfig
import com.huawei.hmf.tasks.OnFailureListener
import com.huawei.hmf.tasks.OnSuccessListener
import com.huawei.hms.mlsdk.common.MLApplication
import com.huawei.hms.mlsdk.model.download.MLLocalModelManager
import com.huawei.hms.mlsdk.model.download.MLModelDownloadListener
import com.huawei.hms.mlsdk.model.download.MLModelDownloadStrategy
import com.huawei.hms.mlsdk.translate.MLTranslateLanguage
import com.huawei.hms.mlsdk.translate.MLTranslatorFactory
import com.huawei.hms.mlsdk.translate.local.MLLocalTranslateSetting
import com.huawei.hms.mlsdk.translate.local.MLLocalTranslator
import com.huawei.hms.mlsdk.translate.local.MLLocalTranslatorModel
import com.translation.assistant.callback.OnModelListener
import com.translation.assistant.callback.TranslateCallback

class OfflineTranslatorManager {
    private var mlLocalTranslator: MLLocalTranslator? = null//离线翻译器
    private var manager: MLLocalModelManager//模型管理器

    constructor(context: Context) {
        Log.d("AssistantManager", "初始化")
        manager = MLLocalModelManager.getInstance()
        setApiKey(context)
    }

    private fun setApiKey(context: Context) {
        val config = AGConnectServicesConfig.fromContext(context)
        MLApplication.getInstance().apiKey = config.getString("client/api_key")
    }

    /**
     * 执行文本离线翻译
     */
    fun translate(input: String, originLang: String = "zh", targetLang: String = "en", callback: TranslateCallback? = null) {
        if(TextUtils.isEmpty(input)){
            callback?.onFailed(1001,"The translated text is empty")
            return
        }
        val supportedLanguages = syncGetLocalAllLanguages()
        if(!supportedLanguages.contains(originLang)){
            callback?.onFailed(1002,"Unsupported language:${originLang}")
            return
        }
        if(!supportedLanguages.contains(targetLang)){
            callback?.onFailed(1003,"Unsupported language:${targetLang}")
            return
        }

        Log.d("AssistantManager", "创建离线翻译器")
        val setting = MLLocalTranslateSetting.Factory() // 设置源语言的编码，使用ISO 639-1标准。此设置为必选项，如果不设置，将可能出现问题。
            .setSourceLangCode(originLang) // 设置目标语言的编码，使用ISO 639-1标准。此设置为必选项，如果不设置，将可能出现问题。
            .setTargetLangCode(targetLang)
            .create()
        mlLocalTranslator?.stop()
        mlLocalTranslator = MLTranslatorFactory.getInstance().getLocalTranslator(setting)
        Log.d("AssistantManager", "开始离线翻译")
        //异步方法
        val startTime = System.currentTimeMillis()
        mlLocalTranslator?.asyncTranslate(input)?.addOnSuccessListener(OnSuccessListener<String> { s ->
            Log.i("AssistantManager", "离线翻译耗时:${System.currentTimeMillis() - startTime}ms")
            mlLocalTranslator?.stop()
            mlLocalTranslator = null
            callback?.onCompleted(s, originLang, targetLang, true)
        })?.addOnFailureListener(OnFailureListener { e ->
            Log.e("AssistantManager", "离线翻译失败: " + e.message)
            mlLocalTranslator?.stop()
            mlLocalTranslator = null
            callback?.onFailed(1004, e.message)
        })

    }

    /**
     * 异步方法获取本地离线翻译所支持的语种
     */
    fun getOfflineTranslatorLang(successLanguage: OnSuccessListener<Set<String>>) {
        //异步方法
        MLTranslateLanguage.getLocalAllLanguages().addOnSuccessListener(successLanguage)
    }

    /**
     * 同步方法获取本地离线翻译所支持的语种
     */
    fun syncGetLocalAllLanguages(): Set<String> {
        val supportedLanguages = MLTranslateLanguage.syncGetLocalAllLanguages()
        Log.d("AssistantManager", "同步方法获取本地离线翻译所支持的语种：${supportedLanguages}")
        return supportedLanguages
    }

    /**
     * 下载语言包：sourceLangCode
     * 下载进度监听器：MLModelDownloadListener
     * 下载成功后回调：OnSuccessListener<Void>
     * 下载失败后回调：OnFailureListener
     */
    fun downloadModel(
        sourceLangCode: String,
        listener: OnModelListener<Void>? = null,
    ) {
        // 获取模型管理器。
        val model = MLLocalTranslatorModel.Factory(sourceLangCode).create()
        // 设置模型下载策略。
        val downloadStrategy = MLModelDownloadStrategy.Factory()
            .needWifi() // 推荐wifi环境下下载。
            .create()

        //下载进度监听器
        val modelDownloadListener =
            MLModelDownloadListener { alreadyDownLength, totalLength ->
                listener?.onProcess(alreadyDownLength, totalLength)
            }
        // 下载模型。
        manager.downloadModel(model, downloadStrategy, modelDownloadListener)
            .addOnSuccessListener{
                listener?.onSuccess(it)
            }
            .addOnFailureListener{
                listener?.onFailure(it)
            }

    }

    fun deleteModel(languageCode: String, listener: OnModelListener<Void>? = null) {
        // 获取模型管理器。
        val model = MLLocalTranslatorModel.Factory(languageCode).create()
        manager.deleteModel(model).addOnSuccessListener {
            listener?.onSuccess(it)
        }.addOnFailureListener {
            listener?.onFailure(it)
        }
    }

}